/**
 * Copyright 2011 Marco Berri - marcoberri@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */
package com.mbfasttrack.controller;

import com.mbfasttrack.model.Geonames;
import com.mbfasttrack.model.Like;
import com.mbfasttrack.model.Media;
import com.mbfasttrack.model.Track;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.WebUtils;

/**
 * @author Marco Berri marcoberri@gmail.com http://tecnicume.blogspot.com
 */
@Controller
public class TrackController extends Base {

    @RequestMapping(value = "/track/savemassimport", method = RequestMethod.POST)
    public String saveMassImport(@ModelAttribute("track") Track track, Model model) {
        org.springframework.security.core.userdetails.User u = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        track = trackService.add(track, u.getUsername());
        trackService.addMassImportData(track, WebUtils.getTempDir(this.context));
        System.err.println("start saveMassImport");

        //allora devo ricevere il file .zip e verificare che sia il file .zip

        return null;
    }

    /**
     *
     * @param track
     * @param model
     * @return
     */
    @RequestMapping(value = "/track/save", method = RequestMethod.POST)
    public String save(@ModelAttribute("track") Track track, Model model) {

        org.springframework.security.core.userdetails.User u = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        track = trackService.add(track, u.getUsername());

        try {
            track = trackService.addMediaMap(track, WebUtils.getTempDir(this.context));
            track = trackService.save(track);

            actionService.add(u.getUsername(), track);
        } catch (Exception e) {
            System.err.println("Problemi nel salvataggio della map:" + e.getMessage());
            log.fatal(e);

            //in caso di non scaricamento devo segnare la track e farlo successivamente in cron
        }

        return "redirect:/track/details/" + track.getSlug();

    }

    /**
     *
     * @param slug
     * @param model
     * @return
     */
    @RequestMapping(value = "/track/delete/{slug}", method = RequestMethod.GET)
    public String delete(@PathVariable String slug, Model model) {

        //TO DO : verificare che sia suo prima di eliminare la tracks!!!

        //spostare questo cosa nel service
        Track t = trackService.trackRepository.findOneBySlug(slug);
        trackService.trackRepository.delete(t);

        //TO DO : devo rimuovoere i valori dei totali sull'utente in caso di elimnazione della tracks

        model.addAttribute("delete", true);
        return "response/ok";
    }

    /**
     *
     * @param slug
     * @param model
     * @return
     */
    @RequestMapping(value = "/track/modify/{slug}", method = RequestMethod.GET)
    public String modify(@PathVariable String slug, Model model) {
        Track track = trackService.trackRepository.findOneBySlug(slug);
        model.addAttribute("track", track);
        return "track/add";
    }

    /**
     *
     * @param slug
     * @param track
     * @param model
     * @return
     */
    @RequestMapping(value = "/track/modify/{slug}/save", method = RequestMethod.POST)
    public String update(@PathVariable String slug, @ModelAttribute("track") Track track, Model model) {
        Track track_loaded = trackService.trackRepository.findOneBySlug(slug);
        track_loaded.setActivity(track.getActivity());
        track_loaded.setName(track.getName());
        track_loaded.setDescription(track.getDescription());
        track_loaded = trackService.save(track_loaded);
        model.addAttribute("track", track_loaded);
        return "track/add";
    }

    /**
     * Dettaglio del tracciato
     *
     * @param type
     * @param slug
     * @param model
     * @return
     */
    @RequestMapping(value = "/track/{type}/{slug}", method = RequestMethod.GET)
    public String getDetails(@PathVariable String type, @PathVariable String slug, Model model) {

        Track track = trackService.trackRepository.findOneBySlug(slug);

        model = getBaseModel(model);
        model.addAttribute("track", track);


        if (type.equalsIgnoreCase("map")) {
            return "track/" + type;
        }

        if (track != null) {
            model.addAttribute("comments", commentService.findAllByObjectId(track.getId()));

            try {
                Page<Geonames> near = geonamesService.getAllNear(track.getStartpoint().getLoc().getX(), track.getStartpoint().getLoc().getY(), 200);
                if (near != null) {
                    model.addAttribute("near", near);
                }
            } catch (Exception e) {
                log.fatal(e);
            }
        }

        return "track/" + type;
    }

    /**
     * Dettaglio del tracciato
     *
     * @param slug
     * @param model
     * @return
     */
    @RequestMapping(value = "/track/like/{slug}", method = RequestMethod.GET)
    public String addLike(@PathVariable String slug, Model model) {

        if (isGuest()) {
            return "redirect:/login";
        }


        Track track = trackService.trackRepository.findOneBySlug(slug);

        org.springframework.security.core.userdetails.User u = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        Like l = likeService.add(track, u.getUsername(), Boolean.TRUE);
        actionService.add(u.getUsername(), l, track);

        return "response/ok";
    }

    /**
     *
     * @param iDisplayLength
     * @param response
     * @param iDisplayStart
     */
    @RequestMapping(value = "/track/json/all", method = RequestMethod.GET)
    public void jsonSearch(@RequestParam(value = "iDisplayLength", required = false) Integer iDisplayLength, @RequestParam(value = "iDisplayStart", required = false) Integer iDisplayStart, HttpServletResponse response) {
        try {
            ;

            int page = 0;
            if (iDisplayStart != null && iDisplayStart != 0) {
                page = iDisplayStart / iDisplayLength;
            }

            Page<Track> tracks = trackService.trackRepository.findAll(new PageRequest(page, iDisplayLength, Sort.Direction.DESC, "dateSaved"));

            if (tracks == null) {
                return;
            }

            ObjectMapper mapper = new ObjectMapper();


            HashMap result = new HashMap();
            result.put("iTotalRecords", tracks.getTotalElements());
            result.put("iTotalDisplayRecords", tracks.getTotalElements());


            NumberFormat formatter = new DecimalFormat("#0.00");

            org.springframework.security.core.userdetails.User u = null;
            try {
                u = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            } catch (Exception e) {
                System.err.println("error load user");
                log.fatal(e);
            }

            ArrayList aaData = new ArrayList();
            for (Track t : tracks.getContent()) {
                ArrayList dati = new ArrayList();

                String media_id = null;
                for (Media m : t.getMedia()) {
                    if (m.getType().equals("staticmap")) {
                        media_id = m.getId();
                    }

                }
                
                
                 
                 
                if (media_id != null) {
                    dati.add("<a href=\"" + sys_site_url + "track/details/" + t.getSlug() + "\"><img src=\"" + sys_site_url + "media/staticmap/" + media_id + "?opts=resized_to_width-100\"/></a>");
                } else {
                    dati.add("NN");
                }
                 
                dati.add("<a href=\"" + sys_site_url + "track/details/" + t.getSlug() + "\">" + t.getName() + "</a>");
               
                 
                dati.add(t.getActivity());

                if (t.getMinAltitude() != null) {
                    dati.add(formatter.format(t.getMinAltitude()));
                } else {
                    dati.add("-");
                }

                if (t.getDislivello() != null) {
                    dati.add(formatter.format(t.getElevation()));
                } else {
                    dati.add("-");
                }


                if (t.getDistance() != null) {
                    dati.add(formatter.format(t.getDistance()));
                } else {
                    dati.add("-");
                }

                dati.add(t.getPublicview());
                dati.add("<a href=\"" + sys_site_url + "dashboard/" + t.getUser().getUsername() + "\">" + t.getUser().getUsername() + "</a>");
                String actions = "<a style=\"padding-left:2px\" href=\"" + sys_site_url + "track/details/" + t.getSlug() + "\"><i class=\"icon-eye-open\" alt=\"view\"></i></a>";

                //è tua questa traccia?
                if (u != null && u.getUsername().equals(t.getUser().getUsername())) {
                    actions += "<a style=\"padding-left:2px\" href=\"" + sys_site_url + "track/modify/" + t.getSlug() + "\"><i class=\"icon-pencil\" alt=\"modify\"></i></a>";
                    actions += "<a style=\"padding-left:2px\" href=\"" + sys_site_url + "track/delete/" + t.getSlug() + "\"><i class=\"icon-remove\" alt=\"remove\"></i></a>";
                }






                if (u != null && likeService.isUserLikeObject(u.getUsername(), t.getId())) {
                    long other = likeService.getCountByObject(t.getId()) - 1;
                    if (other > 0) {
                        actions += "<i class=\"icon-thumbs-up icon-white\"></i> (" + other + ")";
                    } else {
                        actions += "<i class=\"icon-thumbs-up icon-white\"></i>";
                    }

                } else {

                    actions += "<a style=\"padding-left:2px\" href=\"" + sys_site_url + "track/like/" + t.getSlug() + "\"><i class=\"icon-thumbs-up\"></i></a>";
                }

                dati.add(actions);
                aaData.add(dati);

            }

            result.put("aaData", aaData);

            String jsonString = mapper.writeValueAsString(result);

            AbstractHttpMessageConverter<String> stringHttpMessageConverter = new StringHttpMessageConverter();

            MediaType jsonMimeType = MediaType.APPLICATION_JSON;

            if (stringHttpMessageConverter.canWrite(String.class, jsonMimeType)) {

                try {

                    stringHttpMessageConverter.write(jsonString, jsonMimeType, new ServletServerHttpResponse(response));

                } catch (Exception e) {
                    System.err.println(e.getMessage());
                    log.fatal(e);
                }

            }

        } catch (Exception e) {
            System.err.println(e.getMessage());
            log.fatal(e);

        }

    }
}